package service

import (
	"context"
	"errors"
	"fmt"
	"github.com/google/uuid"
	"github.com/robfig/cron"
	"service/basic/config"
	__ "service/basic/proto"
	"service/handler/model"
	"service/untils"
	"strconv"
	"time"
)

// 用户下单
func (s *Server) OrderCreate(_ context.Context, in *__.OrderCreateReq) (*__.OrderCreateResp, error) {
	//接收参数
	var class model.Class
	class.Id = uint(in.ClassId)
	if err := class.GetClassInfoId(); err != nil {
		return nil, errors.New("课程信息查找失败")
	}
	if class.Price == 0 {
		return nil, errors.New("当前课程不存在")
	}
	//检查库存
	if class.Stock <= 0 {
		return nil, errors.New("库存不足")
	}
	var order model.Order
	order.UserId = uint(in.UserId)
	order.ClassId = uint(in.ClassId)
	order.OrderNo = uuid.NewString()
	order.Stock = uint(in.Stock)
	order.Price = class.DisPrice * float64(in.Stock)
	if err := order.Create(); err != nil {
		return nil, errors.New("订单创建失败")
	}

	//分布式锁
	lockKey := fmt.Sprintf("lock:classId:%d", in.ClassId)
	lockId := uuid.NewString()
	lock, err := config.Rdb.SetNX(config.Ctx, lockKey, lockId, time.Hour).Result()
	if err != nil {
		return nil, errors.New("分布式锁异常")
	}
	if lock {
		return nil, errors.New("分布式锁添加失败")
	}

	//调用支付宝支付
	var pay untils.ALiPay
	outTradeNo := order.OrderNo
	totalAmount := order.Price
	payUrl := pay.Payment(outTradeNo, strconv.FormatInt(int64(totalAmount), 10))

	//释放索
	Cron(in.ClassId)

	////扣减商品库存
	//if err := class.RemoveStock(in.Stock); err != nil {
	//	return nil, errors.New("商品库存扣减失败")
	//}
	//
	////更新订单状态
	//if err := order.UpdateStatus(); err != nil {
	//	return nil, errors.New("订单状态更新失败")
	//}

	return &__.OrderCreateResp{
		PayUrl: payUrl,
	}, nil
}

// 设置定时任务
func Cron(classId int64) {
	c := cron.New()
	spec := "* */15 * * * ?"
	err := c.AddFunc(spec, func() {
		//解锁
		lockKey := fmt.Sprintf("lock:classId:%d", classId)
		lockId := uuid.NewString()
		_, err := config.Rdb.Eval(config.Ctx, "", []string{lockKey}, lockId).Result()
		if err != nil {
			panic(err)
		}
	})
	fmt.Println(err)
	c.Start()
}

// 订单信息
func (s *Server) OrderData(_ context.Context, in *__.OrderDataReq) (*__.OrderDataResp, error) {
	var order model.Order
	order.Id = uint(in.Id)
	if err := order.Detail(); err != nil {
		return nil, errors.New("订单信息查询失败")
	}
	return &__.OrderDataResp{
		UserId:  int64(order.UserId),
		ClassId: int64(order.ClassId),
		OrderNo: order.OrderNo,
		Stock:   int64(order.Stock),
		Price:   float32(order.Price),
	}, nil
}
